/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controleur;

import exceptions.AnalyseException;
import exceptions.NoMainFoundError;
import java.awt.event.WindowEvent;
import java.io.FileNotFoundException;
import java.io.IOException;
import vue.Vue;
import Properties.BundleTool;
import application.InterfaceApplication;
import exceptions.ExecutionException;
import exceptions.CodesErreur;
import exceptions.ReadException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.util.Locale;
import outils.ExtracteurFichier;
import outils.SauvegardeFichier;

/**
 * Classe contrôleur faisant le lien entre le model et la vue
 * @author D.Romain
 * @author O.Riad
 */
public class Controleur implements ActionListener, WindowListener {

    private Vue vue;
    private InterfaceApplication model;
    //FICHIERS
    private File temp; //Fichier temporaire
    private File fichierSource; //Fichier source
    //NOMS ET EXTENSIONS
    private static String NOM_FICHIER_TEMP = "source_picol";
    private static String EXTENSTION_FICHIER_TEMP = ".tmp";

    /**
     * Constructeur     *
     * @param pVue vue de l'application
     * @param pModel modèle de l'application
     */
    public Controleur(Vue pVue, InterfaceApplication pModel) {
        this.vue = pVue;
        this.model = pModel;
        this.temp = null;
        this.fichierSource = null;
    }

    /**
     * Action selon les évenements declenchés
     * dans la vue
     * @param ae ActionEvent
     */
    @Override
    public void actionPerformed(ActionEvent ae) {
        String event = ae.getActionCommand();

        //GESTION DE LA LANGUE
        if (event.equals(Vue.FRANCAIS)) {
            BundleTool.setBundle(Locale.FRANCE);
            vue.nommerComposants();
            vue.bloqueItemLangueCourante();
        }
        if (event.equals(Vue.ANGLAIS)) {
            BundleTool.setBundle(Locale.UK);
            vue.nommerComposants();
            vue.bloqueItemLangueCourante();
        }

        //QUITTER
        if (event.equals(Vue.QUITTER)) {
            model.close();
        }

        //GESTION DU MODE
        if (event.equals(Vue.NORMAL)) {
            //Gestion affichage
            vue.griserVariables();
            vue.griserModeDebug(true);
            vue.griserModeNormal(false);
            vue.console.setText("");
            //FIN gestion affichage

        }
        if (event.equals(Vue.DEBUG)) {
            //Gestion affichage
            vue.degriserVariables();
            vue.griserModeDebug(false);
            vue.griserModeNormal(true);
            vue.console.setText("");
            //FIN gestion affichage
        }

        //DEBUG: PAS A PAS
        if (event.equals(Vue.PASAPAS)) {
            //Creation d'un fichier temporaire
            /**
             * Init pour le relancement des interprétations *
             */
            //this.model.initProgram();
            
            //Creation d'un fichier temporaire permettant de recupérer les modifications
            //faites sur le JtextArea du source
            this.recupererModificationSource();

            //Creation du FIleInputStream nécessaire à l'analyse grammaticale
            FileInputStream fips = null;
            try {
                fips = new FileInputStream(this.temp);
                this.model.initDebug(fips);
                this.model.debugExecNextLine();
            } catch (FileNotFoundException ex) {
                vue.addResultat(CodesErreur.code(2));
            } catch (AnalyseException ex) {
                vue.addResultat(CodesErreur.code(5) + "\"" + ex.getDernierToken() + "\"\n"
                        + CodesErreur.code(6) + ex.getLigneToken() + ", "
                        + CodesErreur.code(7) + ex.getColonneToken() + "\n"
                        + CodesErreur.code(8) + "\n" + ex.tokenExpected());
            } catch (ExecutionException e) {
                vue.addResultat(CodesErreur.code(e.getCode()));
            }

            //this.vue.setVariables(this.model.getVariable().toString());

            //Suppression du fichier temporaire lorsque l'on quitte l'application 
            //(Si JVM quittée correctement)
            this.temp.deleteOnExit();
        }

        //LANCER PROGRAMME
        if (event.equals(Vue.LANCER)) {
            /**
             * Init pour le relancement des interprétations *
             */
            vue.setResultat("");
            //this.model.initProgram();

            //Creation d'un fichier temporaire permettant de recupérer les modifications
            //faites sur le JtextArea du source
            this.recupererModificationSource();

            //Creation du FIleInputStream nécessaire à l'analyse grammaticale
            FileInputStream fips = null;
            try {
                fips = new FileInputStream(this.temp);
                this.model.initProgram(fips);
                //Execution effective du programme
                this.model.execute();
            } catch (FileNotFoundException ex) {
                vue.addResultat(CodesErreur.code(2));
            } catch (NoMainFoundError ex) {
                vue.addResultat(CodesErreur.code(1));
            } catch (AnalyseException ex) {
                vue.addResultat(CodesErreur.code(5) + "\"" + ex.getDernierToken() + "\"\n"
                        + CodesErreur.code(6) + ex.getLigneToken() + ", "
                        + CodesErreur.code(7) + ex.getColonneToken() + "\n"
                        + CodesErreur.code(8) + "\n" + ex.tokenExpected());
            } catch (ExecutionException e) {
                vue.addResultat(CodesErreur.codeExpression(e.getCode()));
            }

            //Suppression du fichier temporaire lorsque l'on quitte l'application 
            //(Si JVM quittée correctement)
            this.temp.deleteOnExit();
        }

        //Ouvrir 
        if (event.equals(Vue.OUVRIR)) {
            String src = "";
            this.fichierSource = new File(vue.selectionnerFichierPicol());
            try {
                ExtracteurFichier ex = new ExtracteurFichier(this.fichierSource);
                while (ex.hasNext()) {
                    src += ex.next() + "\n";
                }

            } catch (ReadException ex1) {
                vue.addResultat(CodesErreur.code(3));
            }
            vue.setSource(src);
        }

        if (event.equals(Vue.SAUVEGARDER)) {
            String source = vue.getSource();
            //Si on a un fichier source ouvert
            if (this.fichierSource != null) {
                try {
                    SauvegardeFichier.sauvegarder(source, this.fichierSource);
                } catch (FileNotFoundException ex) {
                    vue.addResultat(CodesErreur.code(2));
                } catch (IOException ex) {
                    vue.addResultat(CodesErreur.code(4));
                }
            } else { //sinon, on enregistre sous...
                File f = new File(vue.enregistrerSous());
                try {
                    SauvegardeFichier.sauvegarder(source, f);
                } catch (FileNotFoundException ex) {
                    vue.addResultat(CodesErreur.code(2));
                } catch (IOException ex) {
                    vue.addResultat(CodesErreur.code(4));
                }
            }
        }
    }

    /**
     * Methode permettant la creation d'un fichier
     * temporaire avec toutes les modifications faites sur le fichier
     * source dans l'interface
     */
    public void recupererModificationSource() {
        if (this.temp == null) {
            try {
                this.temp = File.createTempFile(NOM_FICHIER_TEMP, EXTENSTION_FICHIER_TEMP);
            } catch (IOException ex) {
                vue.addResultat(CodesErreur.code(4));
            }
        }
        //Ecriture dans le fichier temporaire du code source (modifié) de l'interface
        FileWriter fwriter = null;
        try {
            fwriter = new FileWriter(temp);
            fwriter.write(vue.getSource());
        } catch (IOException ex) {
            vue.addResultat(CodesErreur.code(4));
        } finally {
            if (fwriter != null) {
                try {
                    fwriter.close();
                } catch (IOException ex) {
                    vue.addResultat(CodesErreur.code(4));
                }
            }
        }
    }

    @Override
    public void windowOpened(WindowEvent we) {
    }

    @Override
    public void windowClosing(WindowEvent we) {
        System.exit(0);
    }

    @Override
    public void windowClosed(WindowEvent we) {
    }

    @Override
    public void windowIconified(WindowEvent we) {
    }

    @Override
    public void windowDeiconified(WindowEvent we) {
    }

    @Override
    public void windowActivated(WindowEvent we) {
    }

    @Override
    public void windowDeactivated(WindowEvent we) {
    }
}